package com.gitee.wsl.mathematics.level.matrix

import com.gitee.wsl.mathematics.coordinate.Coordinate

/**
 * Represents a matrix of coordinates.
 */
abstract class CoordinateMatrix<T:Number,C: Coordinate<T, *>> : Iterable<C> {

    /**
     * The dimension of the matrix.
     */
    abstract val dimension: Dimension

    /**
     * Gets all the coordinates in this matrix.
     */
    abstract val coordinates: Set<C>

    /**
     * Gets the starting Vector<*> of this matrix.
     */
    abstract val start: C

    final override fun iterator(): Iterator<C> = coordinates.iterator()

    /**
     * Gets the string version of this Vector<*> matrix.
     */
    abstract override fun toString(): String

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other == null) return false
        if (other !is CoordinateMatrix<*,*>) return false

        if (dimension != other.dimension) return false
        if (coordinates != other.coordinates) return false
        if (start != other.start) return false

        return true
    }

    override fun hashCode(): Int {
        var result = dimension.hashCode()
        result = 31 * result + coordinates.hashCode()
        result = 31 * result + start.hashCode()
        return result
    }
}

typealias CoordinateMatrixD<V> = CoordinateMatrix<Double,V>

typealias CoordinateMatrixF<V> = CoordinateMatrix<Float,V>